package com.zlyx.easy.socket;

import java.util.List;

import org.springframework.context.ApplicationContext;

import com.zlyx.easy.core.annotations.ApplicationBean;
import com.zlyx.easy.core.beans.AbstractBean;
import com.zlyx.easy.core.event.IHandlerOnChanged;
import com.zlyx.easy.core.event.IHandlerOnRefreshed;
import com.zlyx.easy.core.map.DefaultMap;
import com.zlyx.easy.core.tool.Ops;
import com.zlyx.easy.core.utils.LogUtils;
import com.zlyx.easy.core.utils.ProxyUtils;
import com.zlyx.easy.core.utils.ThreadManager;
import com.zlyx.easy.socket.annotations.MsgHandler;
import com.zlyx.easy.socket.core.AioTcpMsgHandlerFactory;
import com.zlyx.easy.socket.core.BioTcpMsgHandlerFactory;
import com.zlyx.easy.socket.core.BioUdpMsgHandlerFactory;
import com.zlyx.easy.socket.core.NioTcpMsgHandlerFactory;
import com.zlyx.easy.socket.core.NioUdpMsgHandlerFactory;
import com.zlyx.easy.socket.core.supports.AbstractMsgHandlerFactory;
import com.zlyx.easy.socket.interfaces.IMsgHandler;

/**
 * @Auth 赵光
 * @Describle
 * @2018年12月22日 下午4:41:07
 */
@SuppressWarnings("rawtypes")
@ApplicationBean(todo = { "Socket连接管理平台" })
public class MsgFactoryHandlerManager extends AbstractBean<IMsgHandler>
		implements IHandlerOnRefreshed, IHandlerOnChanged {

	private DefaultMap<AbstractMsgHandlerFactory> factorys = DefaultMap.getInstance();

	@Override
	public void doOnChanged(ApplicationContext context) throws Exception {
		for (String factoryName : factorys.keySet()) {
			factorys.get(factoryName).closeServer();
		}
		LogUtils.info("Easy-socket have been closed!");
	}

	@Override
	public void doOnRefreshed(ApplicationContext applicationContext) {
		try {
			List<IMsgHandler> msgHandlers = getBeans();
			if (Ops.isNotNull(msgHandlers)) {
				AbstractMsgHandlerFactory factory = null;
				MsgHandler msgHandler = null;
				for (IMsgHandler handler : msgHandlers) {
					if (handler.isOpen()) {
						msgHandler = ProxyUtils.getTarget(handler).getClass().getAnnotation(MsgHandler.class);
						factory = getFactory(handler, msgHandler);
						if (factory != null) {
							factorys.put(Ops.getName(handler), factory);
							ThreadManager.execute(factory);
							logger.info("Easy-socket have started an " + msgHandler.type() + " listener on port "
									+ msgHandler.port() + " for " + Ops.getName(handler));
						}
					}
				}
			}
			logger.info("Easy-socket have been started!");
		} catch (Exception e) {
			LogUtils.err(e);
		}
	}

	private AbstractMsgHandlerFactory getFactory(IMsgHandler<?> handler, MsgHandler msgHandler) throws Exception {
		AbstractMsgHandlerFactory factory = null;
		if (msgHandler.isOpen()) {
			int port = msgHandler.port();
			float size = msgHandler.size();
			switch (msgHandler.type()) {
			case BTM: {
				factory = new BioTcpMsgHandlerFactory(port, size, handler);
				break;
			}
			case NTM: {
				factory = new NioTcpMsgHandlerFactory(port, size, handler);
				break;
			}
			case ATM: {
				factory = new AioTcpMsgHandlerFactory(port, size, handler);
				break;
			}
			case BUM: {
				factory = new BioUdpMsgHandlerFactory(port, size, handler);
				break;
			}
			case NUM: {
				factory = new NioUdpMsgHandlerFactory(port, size, handler);
				break;
			}
			}
		}
		return factory;
	}
}
